//模拟堆实现

import java.util.Arrays;

public class MyHeap {
    public int[] elem;
    public int usedSize;

    public MyHeap(){
        this.elem = new int[11];
    }

    public void createHeap(int[] arr){
        for (int i = 0; i < arr.length; i++){
            elem[i] = arr[i];
            usedSize++;
        }
        for (int parent = (usedSize-1-1)/2; parent >= 0; parent--){
            shiftDown(parent, usedSize);
        }
    }

    public void shiftDown(int parent, int len){
        int child = parent * 2 + 1;
        while (child < len){
            //看是否有右孩子
            if (child + 1 < len && elem[child] < elem[child + 1]){
                child++;//左边小就用右孩子和父亲节点比
            }
            if (elem[child] > elem[parent]){
                int tmp = elem[parent];
                elem[parent] = elem[child];
                elem[child] = tmp;
                //交换完成后要继续向下看是否还可以调整
                parent = child;
                child = parent * 2 + 1;
            }else {
                //如果父亲节点都是大根堆，那么孩子一定是大根堆
                break;
            }
        }
    }

    public void shiftUp(int child){
        int parent = (child - 1) / 2;
        while (child > 0){
            //直接判断，因为只针对插入值
            if (elem[child] > elem[parent]){
                int tmp = elem[parent];
                elem[parent] = elem[child];
                elem[child] = tmp;
                child = parent;
                parent = (child - 1) / 2;
            }else {
                break;
            }
        }
    }

    public void offer(int val){
        if (isFull()){
            Arrays.copyOf(this.elem, this.elem.length * 2);
        }
        elem[usedSize++] = val;
        shiftUp(usedSize - 1);
    }

    public boolean isFull(){
        return this.elem.length == usedSize;
    }

    public int poll(int val){
        if (isEmpty()){
            throw new RuntimeException("异常");
        }
        //交换最后一个值和第一个值
        int tmp = elem[0];
        elem[0] = elem[usedSize - 1];
        elem[usedSize - 1] = tmp;
        usedSize--;
        //向下调整堆
        shiftDown(0, usedSize);
        return tmp;
    }

    public boolean isEmpty(){
        return usedSize == 0;
    }

    public void heapSort(){
        int end = usedSize - 1;
        while (end > 0){
            int tmp = elem[end];
            elem[end] = elem[0];
            elem[0] = tmp;
            shiftDown(0, end);
            end--;
        }
    }
}
